﻿using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Travel.CommonUtil.RedisUtil;
using Travel.Data;
using Travel.Data.Consts;
using Travel.Data.Dtos;
using Travel.Data.Entity;
using Travel.Data.Inputs;

namespace Travel.Service.User.Impl
{
    /// <summary>
    /// 角色权限服务实现类
    /// </summary>
    public class RoleAuthorityService : ServiceBase, IRoleAuthorityService
    {
        /// <summary>
        /// 为角色分配权限
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<Results<int>> DistributeAuthority(RoleAuthorityInput input)
        {
            if (!input.ButtonIdList.Any())
            {
                return Results<int>.FailResult("至少选择一个权限分配");
            }
            // 查询当前的角色有哪些权限
            var tabRoleAuthorities = TravelContext.TabRoleAuthorities.AsNoTracking().Where(c => !c.Deleted && c.RoleId == input.RoleId);
            //对比那些权限（按钮）是需要新增，那些是需要被移除
            var oldButtonList = tabRoleAuthorities.Select(c => c.MenuButtonId.Value).ToList();
            //获取那些是按钮是需要新增的
            var needAddButtonIdList = input.ButtonIdList.Except(oldButtonList);
            if (needAddButtonIdList.Any())
            {
                //获取按钮实体类
                var menuButtons = TravelContext.TabMenuButtons.Where(c => !c.Deleted && needAddButtonIdList.Contains(c.Id)).ToList();
                foreach (var c in menuButtons)
                {
                    TravelContext.TabRoleAuthorities.Add(new TabRoleAuthority
                    {
                        Id = SnowIdWorker.NextId(),
                        MenuButtonId = c.Id,
                        RoleId = input.RoleId,
                        CreatedUserId = LoginUserId,
                        UpdatedUserId = LoginUserId,
                        MenuModuleId = c.MenuModuleId
                    });
                }
            }
            //获取那些是按钮是需要删除的
            var needDeleteButtonIdList = oldButtonList.Except(input.ButtonIdList);
            if (needDeleteButtonIdList.Any())
            {
                //获取按钮实体类
                var roleAuthorities = tabRoleAuthorities.Where(c => needDeleteButtonIdList.Contains(c.MenuButtonId.Value));
                foreach (var item in roleAuthorities)
                {
                    TravelContext.TabRoleAuthorities.RemoveRange(item);
                }
            }
            CacheManager.Remove(string.Format(RedisKey.RoleMenuList, input.RoleId));
            return Results<int>.DataResult(await TravelContext.SaveChangesAsync());
        }
        /// <summary>
        /// 获取角色权限列表
        /// </summary>
        /// <param name="loginRoleId"></param>
        /// <returns></returns>
        public async Task<Results<List<AuthorityDto>>> GetAuthoritiesByRoleId(long loginRoleId)
        {
            List<AuthorityDto> dtos = new();
            var tabRoleAuthorities = TravelContext.TabRoleAuthorities.AsNoTracking().Where(c => !c.Deleted && c.RoleId == loginRoleId).Include(c => c.MenuModule).Include(c=>c.MenuButton).ToList();
            var  tabRoles= tabRoleAuthorities.GroupBy(c => c.MenuModuleId);
            foreach (var item in tabRoles)
            {
                AuthorityDto authorityDto = new AuthorityDto()
                {
                    MenuModuleId = item.Key.Value,
                    MenuModuleName = tabRoleAuthorities.FirstOrDefault(c => c.MenuModuleId == item.Key).MenuModule.ModuleName,
                };
                authorityDto.Buttons = item.ToList().Select(c => new AuthorityButtonDto() { 
                
                    ButtonId =  c.MenuButtonId.Value,
                    ButtonName = c.MenuButton.ButtonName
                }).ToList();
                dtos.Add(authorityDto);
            }
            return Results<List<AuthorityDto>>.DataResult(dtos);
        }

        /// <summary>
        /// 获取左边菜单栏
        /// </summary>
        /// <param name="loginRoleId"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<Results<List<LeftMenuDto>>> GetLeftMenuByRoleId(long loginRoleId)
        {
            List<LeftMenuDto> result = CacheManager.GetOrSet(string.Format(RedisKey.RoleMenuList, loginRoleId), () =>
            {
                List<LeftMenuDto> leftMenuDtos = new();
                //当前的角色所能看到的菜单ID列表
                var menIdList = TravelContext.TabRoleAuthorities.AsNoTracking().Where(c => !c.Deleted && c.RoleId == loginRoleId).Select(c => c.MenuModuleId);
                //当前角色看到的菜单
                var tabMenus = TravelContext.TabMenuModules.AsNoTracking().Include(c => c.ParentMenuModule).Where(c => !c.Deleted && menIdList.Contains(c.Id));
                var allParentMenu = tabMenus.Select(c => c.ParentMenuModule);
                HashSet<long> parentIdList = new HashSet<long>();//保存已经构建过的父菜单
                foreach (var parentModule in allParentMenu)
                {
                    if (parentIdList.Add(parentModule.Id))
                    {
                        LeftMenuDto dto = ObjectMapper.Map<LeftMenuDto>(parentModule);
                        var childMenu = tabMenus.Where(c => c.ParentMenuModuleId == parentModule.Id);
                        dto.Child.AddRange(ObjectMapper.Map<List<LeftMenuDto>>(childMenu));
                        leftMenuDtos.Add(dto);
                    }
                }
                return leftMenuDtos;
            }, TimeSpan.FromDays(7));




            return Results<List<LeftMenuDto>>.DataResult(result);
        }
    }
}
